#ifndef VEC2_H_
#define VEC2_H_

template <class T>
class Vec2
{
public:
    /* Default Ctr. */
	Vec2() 
	{
		m_x = 0;
		m_y = 0;
	}
    /* Overloaded Ctr. */
	Vec2( const T x, const T y) 
	{
		m_x = x;
		m_y = y;
	}
    /* Get Functions*/
    T GetX() const
	{
		return m_x;
	}
	T GetY() const
	{
		return m_y;
	}
    /* Set Functions*/
	void SetX(const T x)
	{
		m_x = x;
	}
	void SetY(const T y)
	{
		m_y = y;
	}
    /* Adds the given vector to this*/
	Vec2& operator+=(const Vec2& rhs)
	{
		m_x += rhs.m_x;
		m_y += rhs.m_y;
		return *this;
	}
    /* returns a vector of the given value added to this*/
    Vec2 operator+(const Vec2& rhs) const
    {
        return Vec2(m_x + rhs.GetX(), m_y + rhs.GetY());
    }
    /* Minuses the given vector from this*/
	Vec2& operator-=(const Vec2& rhs)
	{
		m_x -= rhs.m_x;
		m_y -= rhs.m_y;
		return *this;
	}
    /* returns a vector of the given minused from this*/
    Vec2 operator-(const Vec2& rhs) const
    {
        return Vec2(m_x - rhs.GetX(), m_y - rhs.GetY());
    }
    /* multiplies the vector by the given value*/
	Vec2& operator *= (const T f)
	{
		m_x *= f;
		m_y *= f;
		return *this;
	}
    /* returns a value of the given scalar muliplied by this*/
    Vec2 operator*(const T f) const
    {
        return Vec2(m_x * f, m_y * f);
    }
    /* Index operators returning by value or reference. 
    depending on constness */
    T operator[](unsigned i) const
    {
        if (i == 0) return m_x;
        return m_y;
    }

    T& operator[](unsigned i) 
    {
        if (i == 0) return m_x;
        return m_y;
    }

    Vec2 GetInverted() const
    {
        return Vec2(-m_x, -m_y);
    }

    void SetStats(T x, T y)
    {
        m_x = x;
        m_y = y;
    }

private:
	T m_x;
	T m_y;
};

template <class T>
Vec2<T> operator+( const Vec2<T>& a, const Vec2<T>& b)
{
	Vec2<T> result = a;
	result += b;
	return result;
}

template <class T>
Vec2<T> operator*(const Vec2<T>& one, float two)
{
	Vec2<T> result = one;
	result *= two;
	return result;
}

typedef Vec2<int> Vec2i;
typedef Vec2<float> Vec2f;


#endif